#include "IGamePlay.h"

IGamePlay::IGamePlay()
{

};

IGamePlay::IGamePlay(HINSTANCE hInstance, GAME_SCREEN_RESOLUSION Mode, bool IsFullScreen, int frameRate)
{
	m_hInstance	=	hInstance;
	m_hWnd		=	NULL;
	m_Mode		=	Mode;

	SetScreenDimension();

	m_IsFullScreen	=	IsFullScreen;
	g_FPS			=	frameRate;
}

//------------------------------------------//
// Name : SetScreenDimension                //
// Desc : Use to set the screen resolution  //
//------------------------------------------//
void IGamePlay::SetScreenDimension()
{
	switch(m_Mode)
	{
	case GAME_SCREEN_RESOLUTION_640_480:
		g_ScreenWidth	= 640;
		g_ScreenHeight	= 480;
		break;
	case GAME_SCREEN_RESOLUTION_800_600:
		g_ScreenWidth	= 800;
		g_ScreenHeight	= 600;
		break;
	case GAME_SCREEN_RESOLUTION_1024_768:
		g_ScreenWidth	= 1024;
		g_ScreenHeight	= 768;
		break;
	default:
		g_ScreenWidth	= 800;
		g_ScreenHeight	= 600;
		break;
	}
}


IGamePlay::~IGamePlay()
{
	Release();
}

//---------------------------//
// Name : Release            //
// Desc : Use to free memory //
//---------------------------//
void IGamePlay::Release()
{
	m_hInstance = NULL;
	if(m_hWnd)
	{
		DestroyWindow(m_hWnd);
		m_hWnd	= NULL;
	}

	if(m_Graphic)
	{
		m_Graphic->Release();
	}
	if(m_Input)
	{
		m_Input->Release();
	}
	m_Graphic	= NULL;
	m_Input		= NULL;
	m_Timer		= NULL;
}


//------------------------------------------------------//
// Name : WndProc                                       //
// Desc : The window procedure to handle window message //
//------------------------------------------------------//
LRESULT CALLBACK IGamePlay::WndProc(HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam)
{
	// If this is a create message, trap the 'this' pointer passed in and store it within the window.
    if ( msg == WM_CREATE ) SetWindowLong( hwnd, GWL_USERDATA, (LONG)((CREATESTRUCT FAR *)lParam)->lpCreateParams);

    // Obtain the correct destination for this message
    IGamePlay *Destination = (IGamePlay*)GetWindowLong( hwnd, GWL_USERDATA );
    
    // If the hWnd has a related class, pass it through
    if (Destination) 
		return Destination->DisplayWndProc( hwnd, msg, wParam, lParam );
    
    // No destination found, defer to system...
    return DefWindowProc( hwnd, msg, wParam, lParam );
}



//--------------------------------------------------------------------------//
// Name : DisplayWndProc													//
// Desc : The display devices internal WndProc function. All messages being //
//        passed to this function are relative to the window it owns.		//
//--------------------------------------------------------------------------//
LRESULT IGamePlay::DisplayWndProc(HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam)
{
	return DefWindowProc(hwnd, msg, wParam, lParam);
}

//------------------------------------------------------------------------------//
//	Name : IniWindow                                                            //
//	Desc : Fill and Register windows class , create window , show and update it //
//------------------------------------------------------------------------------//
bool IGamePlay::InitWindow()
{
	WNDCLASS wndclass;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndclass.hCursor = LoadCursor(NULL, IDI_APPLICATION);
	wndclass.hIcon = LoadIcon(NULL, IDC_ARROW);
	wndclass.hInstance = m_hInstance;
	wndclass.lpfnWndProc = WndProc;
	wndclass.lpszClassName = g_strAppName;
	wndclass.lpszMenuName = NULL;
	wndclass.style = CS_HREDRAW | CS_VREDRAW;

	if( !( RegisterClass(&wndclass) ) )
		return false;

	DWORD Style;

	Style = m_IsFullScreen ? WS_EX_TOPMOST|WS_POPUP|WS_VISIBLE: WS_OVERLAPPEDWINDOW;

	m_hWnd = CreateWindow( g_strAppName, 
						   g_strAppName,
						   Style,
						   CW_USEDEFAULT,
						   CW_USEDEFAULT,
						   g_ScreenWidth,
						   g_ScreenHeight,
						   NULL,
						   NULL,
						   m_hInstance,
						   this
						   );

	if(!m_hWnd)
		return false;

	ShowWindow(m_hWnd , SW_SHOW);
	UpdateWindow(m_hWnd);

	return true;
}

//-------------------------------------------------------------------------------------//
// Name : GameInit                                                                     //
// Desc : Use to init window , graphic , time and input ,after all Init the game state //
//-------------------------------------------------------------------------------------//
bool IGamePlay::GameInit()
{
	if(!InitWindow())
		return false;

	//TODO init Graphic
	m_Graphic = new CGraphic(m_hWnd , m_hInstance , g_ScreenWidth , g_ScreenHeight , m_IsFullScreen);
	if(!m_Graphic->Init())
		return false;
	if(!m_Graphic->InitSpriteHandler())
		return false;

	//TODE init Timer
	m_Timer	= CTimer::GetInstance(); 

	//TODO init Input
	m_Input = new CInput();

	if( !m_Input->CreateInput() )
		return false;

	if( !m_Input->InitKeyboard(m_hWnd) )
		return false;

	if( !m_Input->InitMouse(m_hWnd) )
		return false;
	
	m_StateManager = new CStateManager(this);

	Init();

	return true;
}

//----------------------//
// Name : GameRun       //
// Desc : Main game run //
//----------------------//
void IGamePlay::GameRun()
{
	MSG	msg;

	m_Timer->Start();
	while(1)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);

		}
		else
		{
			//TODO update , render game
			g_DeltaTime = m_Timer->Tick();
			if( g_DeltaTime > 1.0f/(float)g_FPS )
			{
				m_Timer->FreshTime();
				m_Input->ProcessKey(m_hWnd);
				m_Input->GetMouse();
				Update();
				Render();
				char c[100];
				sprintf(c,"Frame rate = %f , FPS = %d",m_Timer->GetFrameRate(),g_FPS);
				SetWindowText( m_hWnd, c );
			}
		}
	}
}

//--------------------------------------------//
// Name : GameEnd                             //
// Desc : End game here , time to free memory //
//--------------------------------------------//
void IGamePlay::GameEnd()
{
	Destroy();
	Release();
}